﻿
Imports System.Threading

Public Module _delegate
    Public Delegate Sub void()
    Public Delegate Sub void(Of T)(ByRef i As T)
    Public Delegate Sub void(Of T1, T2)(ByRef i1 As T1, ByRef i2 As T2)
    Public Delegate Sub void(Of T1, T2, T3)(ByRef i1 As T1, ByRef i2 As T2, ByRef i3 As T3)
    Public Delegate Sub void(Of T1, T2, T3, T4)(ByRef i1 As T1, ByRef i2 As T2, ByRef i3 As T3, ByRef i4 As T4)
    Public Delegate Sub void(Of T1, T2, T3, T4, T5)(ByRef i1 As T1,
                                                    ByRef i2 As T2,
                                                    ByRef i3 As T3,
                                                    ByRef i4 As T4,
                                                    ByRef i5 As T5)

    Public Delegate Function _do(Of RT)() As RT
    Public Delegate Function _do(Of T, RT)(ByRef i As T) As RT
    Public Delegate Function _do(Of T, T2, RT)(ByRef i As T, ByRef i2 As T2) As RT
    Public Delegate Function _do(Of T, T2, T3, RT)(ByRef i As T, ByRef i2 As T2, ByRef i3 As T3) As RT
    Public Delegate Function _do(Of T, T2, T3, T4, RT)(ByRef i As T,
                                                       ByRef i2 As T2,
                                                       ByRef i3 As T3,
                                                       ByRef i4 As T4) As RT
    Public Delegate Function _do(Of T, T2, T3, T4, T5, RT)(ByRef i As T,
                                                           ByRef i2 As T2,
                                                           ByRef i3 As T3,
                                                           ByRef i4 As T4,
                                                           ByRef i5 As T5) As RT

    Public Delegate Function stringcheck(ByVal s As String, ByVal index As Int64, ByRef inc As Int64) As Boolean
    Public Delegate Function charcheck(ByVal c As Char) As Boolean

    Public Function do_(Of RT)(ByVal value As RT) As _do(Of RT)
        Return Function() As RT
                   Return value
               End Function
    End Function

    Public Function do_(Of RT)(ByVal d As _do(Of RT), ByVal falseValue As RT) As RT
        If d Is Nothing Then
            Return falseValue
        End If
        Return do_(Function(ByRef n1 As Byte,
                            ByRef n2 As Byte,
                            ByRef n3 As Byte,
                            ByRef n4 As Byte,
                            ByRef n5 As Byte) As RT
                       Return d()
                   End Function, 0, 0, 0, 0, 0, falseValue)
    End Function

    Public Function do_(Of RT)(ByVal v As void(Of RT), ByVal falseValue As RT) As RT
        If v Is Nothing Then
            Return falseValue
        End If
        Return do_(Function() As RT
                       Dim r As RT = Nothing
                       v(r)
                       Return r
                   End Function,
                   falseValue)
    End Function

    Public Function do_(Of T, RT)(ByVal d As _do(Of T, RT), ByRef i As T, ByVal falseValue As RT) As RT
        If d Is Nothing Then
            Return falseValue
        End If
        Return do_(Function(ByRef j As T,
                            ByRef n2 As Byte,
                            ByRef n3 As Byte,
                            ByRef n4 As Byte,
                            ByRef n5 As Byte) As RT
                       Return d(j)
                   End Function, i, 0, 0, 0, 0, falseValue)
    End Function

    Public Function do_(Of T1, T2, RT)(ByVal d As _do(Of T1, T2, RT), ByRef i1 As T1, ByRef i2 As T2,
                                       ByVal falseValue As RT) As RT
        If d Is Nothing Then
            Return falseValue
        End If
        Return do_(Function(ByRef j1 As T1,
                            ByRef j2 As T2,
                            ByRef n3 As Byte,
                            ByRef n4 As Byte,
                            ByRef n5 As Byte) As RT
                       Return d(j1, j2)
                   End Function, i1, i2, 0, 0, 0, falseValue)
    End Function

    Public Function do_(Of T1, T2, T3, RT)(ByVal d As _do(Of T1, T2, T3, RT),
                                           ByRef i1 As T1, ByRef i2 As T2, ByRef i3 As T3,
                                           ByVal falseValue As RT) As RT
        If d Is Nothing Then
            Return falseValue
        End If
        Return do_(Function(ByRef j1 As T1,
                            ByRef j2 As T2,
                            ByRef j3 As T3,
                            ByRef n4 As Byte,
                            ByRef n5 As Byte)
                       Return d(j1, j2, j3)
                   End Function, i1, i2, i3, 0, 0, falseValue)
    End Function

    Public Function do_(Of T1, T2, T3, T4, RT)(ByVal d As _do(Of T1, T2, T3, T4, RT),
                                               ByRef i1 As T1, ByRef i2 As T2, ByRef i3 As T3, ByRef i4 As T4,
                                               ByVal falseValue As RT) As RT
        If d Is Nothing Then
            Return falseValue
        End If
        Return do_(Function(ByRef j1 As T1,
                            ByRef j2 As T2,
                            ByRef j3 As T3,
                            ByRef j4 As T4,
                            ByRef n5 As Byte)
                       Return d(j1, j2, j3, j4)
                   End Function, i1, i2, i3, i4, 0, falseValue)
    End Function

    Public Function do_(Of T1, T2, T3, T4, T5, RT)(ByVal d As _do(Of T1, T2, T3, T4, T5, RT),
                                                   ByRef i1 As T1,
                                                   ByRef i2 As T2,
                                                   ByRef i3 As T3,
                                                   ByRef i4 As T4,
                                                   ByRef i5 As T5,
                                                   ByVal falseValue As RT) As RT
        If d Is Nothing Then
            Return falseValue
        End If
        Try
            Return d(i1, i2, i3, i4, i5)
        Catch ex As ThreadAbortException
            raiseError("thread abort.", errorHandle.errorType.warning)
            Return falseValue
        Catch ex As Exception
            raiseError(errorHandle.errorType.critical,
                       "caught unhandled exception, type ", ex.GetType().FullName(), ", ex ", ex.Message(), _
                       ", callstack ", ex.StackTrace())
            Return falseValue
        End Try
    End Function

    Public Function _void(ByVal v As void) As void
        Return v
    End Function

    Public Sub void_(ByVal d As void)
        If d Is Nothing Then
            Return
        End If
        do_(Function(ByRef n1 As Byte,
                     ByRef n2 As Byte,
                     ByRef n3 As Byte,
                     ByRef n4 As Byte,
                     ByRef n5 As Byte) As Byte
                d()
                Return 0
            End Function, 0, 0, 0, 0, 0, 0)
    End Sub

    Public Sub void_(Of T)(ByVal d As void(Of T), ByRef i As T)
        If d Is Nothing Then
            Return
        End If
        do_(Function(ByRef j As T,
                     ByRef n2 As Byte,
                     ByRef n3 As Byte,
                     ByRef n4 As Byte,
                     ByRef n5 As Byte) As Byte
                d(j)
                Return 0
            End Function, i, 0, 0, 0, 0, 0)
    End Sub

    Public Sub void_(Of T1, T2)(ByVal d As void(Of T1, T2), ByRef i1 As T1, ByRef i2 As T2)
        If d Is Nothing Then
            Return
        End If
        do_(Function(ByRef j1 As T1,
                     ByRef j2 As T2,
                     ByRef n3 As Byte,
                     ByRef n4 As Byte,
                     ByRef n5 As Byte) As Byte
                d(j1, j2)
                Return 0
            End Function, i1, i2, 0, 0, 0, 0)
    End Sub

    Public Sub void_(Of T1, T2, T3)(ByVal d As void(Of T1, T2, T3), ByRef i1 As T1, ByRef i2 As T2, ByRef i3 As T3)
        If d Is Nothing Then
            Return
        End If
        do_(Function(ByRef j1 As T1,
                     ByRef j2 As T2,
                     ByRef j3 As T3,
                     ByRef n4 As Byte,
                     ByRef n5 As Byte) As Byte
                d(j1, j2, j3)
                Return 0
            End Function, i1, i2, i3, 0, 0, 0)
    End Sub

    Public Sub void_(Of T1, T2, T3, T4)(ByVal d As void(Of T1, T2, T3, T4),
                                        ByRef i1 As T1,
                                        ByRef i2 As T2,
                                        ByRef i3 As T3,
                                        ByRef i4 As T4)
        If d Is Nothing Then
            Return
        End If
        do_(Function(ByRef j1 As T1,
                     ByRef j2 As T2,
                     ByRef j3 As T3,
                     ByRef j4 As T4,
                     ByRef n5 As Byte) As Byte
                d(j1, j2, j3, j4)
                Return 0
            End Function, i1, i2, i3, i4, 0, 0)
    End Sub

    Public Sub void_(Of T1, T2, T3, T4, T5)(ByVal d As void(Of T1, T2, T3, T4, T5),
                                            ByRef i1 As T1,
                                            ByRef i2 As T2,
                                            ByRef i3 As T3,
                                            ByRef i4 As T4,
                                            ByRef i5 As T5)
        If d Is Nothing Then
            Return
        End If
        do_(Function(ByRef j1 As T1,
                     ByRef j2 As T2,
                     ByRef j3 As T3,
                     ByRef j4 As T4,
                     ByRef j5 As T5) As Byte
                d(j1, j2, j3, j4, j5)
                Return 0
            End Function, i1, i2, i3, i4, i5, 0)
    End Sub

    Public Function true_(ByVal v As void) As Boolean
        void_(v)
        Return True
    End Function

    Public Function false_(ByVal v As void) As Boolean
        void_(v)
        Return False
    End Function

    Public Function reverse(ByVal d As _do(Of Boolean)) As _do(Of Boolean)
        If d Is Nothing Then
            Return do_(True)
        Else
            Return Function() As Boolean
                       Return Not d()
                   End Function
        End If
    End Function
End Module
